/**
 *
 *  @author   ghh
 *  @version  1.0
 */
define(['common', 'hciMouseMenu'], function (common, HCIMouseMenu) {
    var HCIDbDesigner = function (params) {
        var self = this;
        self.init();
        self.params = $.extend(true, {}, self.params, params);
        self.initPaper();
        self.initMouseMenu();
        $(document).mousemove(function (e) {
            if (self.temFrom) {
                var eX = e.pageX - 350;
                var eY = e.pageY - 80;
                var fromPoint = self.getRectLinkPoint(self.temFrom, {x: eX, y: eY});
                self.temFromPoint = fromPoint;
                if (self.temLine) {
                    self.temLine.attr({"path": "M" + fromPoint.x + " " + fromPoint.y + " L" + eX + " " + eY});
                    self.temLine.node.style.cssText = "stroke-dasharray:2"
                }
            }
        });
        $(document).mouseup(function () {
            if (self.temLine) {
                self.temLine.remove();
                self.temFromPoint = {x: 0, y: 0};
                self.temLine = null;
                self.temFrom = null;
                self.temTo = null;
            }
        });
    };
    //参数
    HCIDbDesigner.prototype.params = {
        target: '',
        basePath: window.GLOBAL_WEB_BASE_PATH + "/image/icons/",
        data: [],
        getTableName: null,
        shapePro: {
            rectAttr: {"stroke": "#0080C0", "stroke-width": "0.5px", "fill": '45-#BADAFC-#F0F7FE'},
            rectActiveAttr: {"stroke": "#f8d269", "stroke-width": "1px", "fill": '90-#fae893-#fffffd'},
            textTableCodeAttr: {"text-anchor": "start", "font-size": "12px"},
            tableIconImage: 'table.png'
        },
        mouseMenuData: [
            [
                {
                    itemId: "del",
                    text: "删除",
                    func: function () {

                    }
                }
            ]
        ],
        contentMenuEvent: null,
        beforeLoadData: null,
        afterAddShape: null,
        afterShapeActive: null,//激活后事件
        afterCancelShapeActive: null,//取消激活事件
        afterAddLink: null,//连线后事件
        afterDelShape: null//删除后事件
    };
    HCIDbDesigner.prototype.init = function () {
        var self = this;
        self.maxX = 0;
        self.maxY = 0;
        self.mouseStatus = "select";//设置鼠标状态：select 选择移动状态；link 连线状态
        self.stroeShapes = {};//存储表图形
        self.stroeLines = {};//存储线
        self.temLine = null;//缓存线
        self.temFrom = null;//缓存开始节点
        self.temTo = null;//缓存目标节点
        self.activeShape = null;//激活的表图形
        self.temFromPoint = {x: 0, y: 0};
    };
    //初始化画布
    HCIDbDesigner.prototype.initPaper = function () {
        var self = this,
            _w = $("#" + self.params.target).width(),
            _h = $("#" + self.params.target).height();
        self.paper = Raphael(self.params.target, _w, _h);
        self.maxX = _w;
        self.maxY = _h;
    };
    //调整画布大小
    HCIDbDesigner.prototype.setPageSize = function (rect) {
        var self = this;
        var _x = rect.attr("x");
        var _y = rect.attr("y");
        var _w = rect.getBBox().width;
        var _h = rect.getBBox().height;
        var lx = _x + _w + 22, ly = _y + _h + 22;
        self.maxX = Math.max(self.maxX, lx);
        self.maxY = Math.max(self.maxY, ly);
        self.paper.setSize(self.maxX, self.maxY);
    };
    //添加矩形框
    HCIDbDesigner.prototype.addShape = function (x, y, data, isActive) {
        var self = this;
        var w = 200, h = 28;
        //绘制外框
        var rect = self.paper.rect(x, y, w, h);
        rect.attr(self.params.shapePro.rectAttr);

        //绘制tableIcon
        var tableIcon = self.params.basePath + self.params.shapePro.tableIconImage;
        var imageTableIconPoint = function (x, y) {
            return {x: x + 8, y: y + h / 2 - 9};
        }
        var imageTableIcon = self.paper.image(tableIcon, imageTableIconPoint(x, y).x, imageTableIconPoint(x, y).y, 18, 18);
        //绘制表名
        var tableCode = self.params.getTableName(data);//获取表名
        var textTableCodePoint = function (x, y) {
            return {x: x + 32, y: y + h / 2};
        }
        var textTableCode = self.paper.text(textTableCodePoint(x, y).x, textTableCodePoint(x, y).y, tableCode);
        textTableCode.attr(self.params.shapePro.textTableCodeAttr);
        var shapeId = data["id"];
        rect.data("id", shapeId);
        textTableCode.data("id", shapeId);
        self.stroeShapes[shapeId] = {
            rect: rect,
            textTableCode: textTableCode,
            imageTableIcon: imageTableIcon,
            data: data
        };
        if (isActive) {
            self.setActive(shapeId);
        }
        var onStart = function () {
            x = rect.attr("x");
            y = rect.attr("y");
            rect.attr({opacity: 0.2});
            imageTableIcon.attr({opacity: 0.5});
            textTableCode.attr({opacity: 0.5});
        };
        var onMove = function (dx, dy) {
            if (self.mouseStatus == "select") {
                var ox = dx + x;
                var oy = dy + y;
                if (ox > 0 && oy > 0) {
                    rect.attr({x: ox, y: oy});
                    imageTableIcon.attr({x: imageTableIconPoint(ox, oy).x, y: imageTableIconPoint(ox, oy).y});
                    textTableCode.attr({x: textTableCodePoint(ox, oy).x, y: textTableCodePoint(ox, oy).y});
                    var curId = rect.data("id");
                    $.each(self.stroeLines, function (index, item) {
                        var temFrom = null, temTo = null;
                        if (item.fromId == curId) {
                            temFrom = self.stroeShapes[curId].rect;
                            temTo = self.stroeShapes[item.toId].rect;
                            var linePoint = self.getLinePoints(temFrom, temTo);
                            item.line.attr({"path": "M" + linePoint.from.x + " " + linePoint.from.y + " L" + linePoint.to.x + " " + linePoint.to.y});
                        } else if (item.toId == curId) {
                            temFrom = self.stroeShapes[item.fromId].rect;
                            temTo = self.stroeShapes[curId].rect;
                            var linePoint = self.getLinePoints(temFrom, temTo);
                            item.line.attr({"path": "M" + linePoint.from.x + " " + linePoint.from.y + " L" + linePoint.to.x + " " + linePoint.to.y});
                        }
                    });
                }
            }
        };
        var onEnd = function () {
            rect.attr({opacity: 1});
            imageTableIcon.attr({opacity: 1});
            textTableCode.attr({opacity: 1});
            self.setPageSize(rect);
        };
        $.each(self.stroeShapes[shapeId], function (index, shape) {
            if (index == "data") {
                return false;
            }

            shape.drag(function (dx, dy) {
                onMove(dx, dy);
            }, function () {
                onStart();
            }, function () {
                onEnd();
            });
            shape.hover(function () {
                if (self.mouseStatus == "link") {
                    this.attr({"cursor": "crosshair"});
                } else {
                    this.attr({"cursor": "default"});
                }
            });

            shape.mousedown(function () {
                if (self.mouseStatus == "link") {
                    self.temLine = self.addLine({x: 0, y: 0}, {x: 0, y: 0});
                    self.temFrom = rect;
                    self.temLine.node.style.cssText = "stroke-dasharray:2";
                }
            });
            shape.mouseup(function () {
                //起点跟终点不是同一个
                if (self.temFrom && self.temFrom.data("id") != shape.data("id")) {
                    self.temTo = self.stroeShapes[shapeId].rect;
                    var linePoints = self.getLinePoints(self.temFrom, self.temTo);
                    if (self.temLine) {
                        //验证连线有效性
                        var temFromId = self.temFrom.data("id");
                        var temToId = self.temTo.data("id");
                        var isValidLine = true;
                        $.each(self.stroeLines, function (lineIndex, lineItem) {
                            if (temFromId == lineItem["fromId"] && temToId == lineItem["toId"]) {
                                isValidLine = false;
                                return false;
                            } else if (temFromId == lineItem["toId"] && temToId == lineItem["fromId"]) {
                                isValidLine = false;
                                return false;
                            }
                        });
                        if (isValidLine) {
                            //绘线
                            var line = self.addLine(linePoints.from, linePoints.to);
                            var lineId = common.guid();
                            self.stroeLines[lineId] = {
                                fromId: self.temFrom.data("id"),
                                toId: self.temTo.data("id"),
                                line: line
                            };

                            if (typeof (self.params.afterAddLink) == "function") {
                                self.params.afterAddLink(self.temFrom.data("id"), self.temTo.data("id"));
                            }
                        }
                    }
                }
            });
            shape.click(function () {
                var shapeId = this.data("id");
                self.setActive(shapeId);
            });

            //鼠标右键处理
            $(shape.node).on("contextmenu", function () {
                self.setActive(shapeId);
            })
            self.mouseMenuObj.show($(shape.node));
        });
        if (typeof(self.params.afterAddShape) == "function") {
            self.params.afterAddShape(shapeId);
        }
    };
    //添加连线
    HCIDbDesigner.prototype.addLine = function (from, to) {
        var line = this.paper.path("M" + from.x + " " + from.y + " L" + to.x + " " + to.y);
        line.attr({
            stroke: "#7993e2",
            "stroke-width": "1.5px",
            "arrow-end": "classic-wide-long"
        });
        return line;
    };
    //获取节点中间坐标
    HCIDbDesigner.prototype.getRectMidPoint = function (rect) {
        var shapeAttr = rect.getBBox();
        var x = shapeAttr.x, y = shapeAttr.y, w = shapeAttr.width, h = shapeAttr.height;
        var mX = x + w / 2;
        var mY = y + h / 2;
        return {x: mX, y: mY};
    };
    //通过一点获取Rect连线的坐标
    HCIDbDesigner.prototype.getRectLinkPoint = function (rect, point) {
        //矩形计算
        //计算中间点
        var rectAttr = rect.getBBox();
        var x = rectAttr.x, y = rectAttr.y, w = rectAttr.width, h = rectAttr.height;
        var mX = x + w / 2, mY = y + h / 2;
        var eX = point.x, eY = point.y;
        var sX = mX, sY = mY;
        var tanA = (h / 2) / (w / 2);
        //左上方
        if (eX < mX && eY < mY) {
            var _tanA = (mY - eY) / (mX - eX);
            if (tanA <= _tanA) {
                //东北方向偏北
                sY = mY - h / 2;
                sX = mX - (h / 2) * (mX - eX) / (mY - eY);
            } else {
                //东北方向偏东
                sX = mX - w / 2;
                sY = mY - (w / 2) * (mY - eY) / (mX - eX);
            }
        }
        //左下方
        else if (eX < mX && eY > mY) {
            var _tanA = (eY - mY) / (mX - eX);
            if (tanA >= _tanA) {
                //东南方向偏东
                sX = mX - w / 2;
                sY = mY + (w / 2) * (eY - mY) / (mX - eX);
            } else {
                //东南方向偏南
                sY = mY + h / 2;
                sX = mX - (h / 2) * (mX - eX) / (eY - mY);
            }
        }
        //右上方
        else if (eX > mX && eY < mY) {
            var _tanA = (mY - eY) / (eX - mX);
            if (_tanA >= tanA) {
                //西北方向偏北
                sY = mY - (h / 2);
                sX = mX + (h / 2) * (eX - mX) / (mY - eY);
            } else {
                //东北方向偏东
                sX = mX + (w / 2);
                sY = mY - (w / 2) * (mY - eY) / (eX - mX);
            }
        }
        //右下方
        else if (eX > mX && eY > mY) {
            var _tanA = (eY - mY) / (eX - mX);
            if (_tanA < tanA) {
                //西南偏西
                sX = mX + (w / 2);
                sY = mY + (w / 2) * (eY - mY) / (eX - mX);
            } else {
                //西南偏南
                sY = mY + (h / 2);
                sX = mX + (h / 2) * (eX - mX) / (eY - mY);
            }
        }
        return {x: sX, y: sY};
    }
    //添加两个节点之间的连线开始结束坐标
    HCIDbDesigner.prototype.getLinePoints = function (rect1, rect2) {
        var self = this;
        var shape1MidPoint = self.getRectMidPoint(rect1), shape2MidPoint = self.getRectMidPoint(rect2);
        var fromPoint = self.getRectLinkPoint(rect1, shape2MidPoint);
        var toPoint = self.getRectLinkPoint(rect2, shape1MidPoint);
        return {from: fromPoint, to: toPoint};
    };

    //设置激活节点
    HCIDbDesigner.prototype.setActive = function (shapeId, isNoAfterEvent) {
        var self = this;
        self.cancelShapeActive();
        self.activeShape = self.stroeShapes[shapeId];
        self.activeShape.rect.attr(self.params.shapePro.rectActiveAttr);
        self.activeShape.rect.node.style.cssText = "stroke-dasharray:2";
        if (typeof(self.params.afterShapeActive) == "function" && !isNoAfterEvent) {
            self.params.afterShapeActive(shapeId);
        }
    };
    //全部取消选中
    HCIDbDesigner.prototype.cancelShapeActive = function () {
        var self = this;
        if (self.activeShape && self.activeShape.rect.node) {
            self.activeShape.rect.attr(self.params.shapePro.rectAttr);
            self.activeShape.rect.node.style.cssText = "";
            self.activeShape = null;
        }
    }
    //加载数据
    HCIDbDesigner.prototype.loadData = function (data) {
        var self = this;
        if (typeof(self.params.beforeLoadData) == "function") {
            self.params.beforeLoadData(data);
        }
        var shapes = data["shapes"], lines = data["lines"];
        $.each(shapes, function (index, item) {
            self.addShape(item["x"], item['y'], item["data"])
        });
        $.each(lines, function (index, item) {
            var fromId = item["fromId"], toId = item["toId"];
            var linePoints = self.getLinePoints(self.stroeShapes[fromId]["rect"], self.stroeShapes[toId]["rect"]);
            var line = self.addLine(linePoints.from, linePoints.to);
            self.stroeLines[index] = {
                fromId: fromId,
                toId: toId,
                line: line
            };
        });
    };
    //设置鼠标状态：select 选择移动状态；link 连线状态
    HCIDbDesigner.prototype.setMouseStatus = function (mouseType) {
        var self = this;
        self.mouseStatus = mouseType;
    };

    HCIDbDesigner.prototype.initMouseMenu = function () {
        var self = this;
        self.mouseMenuObj = new HCIMouseMenu({
            name: 'dbDesignerMouseMenu',
            data: self.params.mouseMenuData
        })
    };
    HCIDbDesigner.prototype.getActiveShapeId = function () {
        var self = this;
        var shapeId = self.activeShape.rect.data("id");
        alert(shapeId);
        return shapeId;
    };
    HCIDbDesigner.prototype.delShape = function (shapeId) {
        var self = this;
        //移除节点
        self.stroeShapes[shapeId].rect.remove();
        self.stroeShapes[shapeId].imageTableIcon.remove();
        self.stroeShapes[shapeId].textTableCode.remove();
        delete self.stroeShapes[shapeId];
        //移除连线
        $.each(self.stroeLines, function (lineId, lineItem) {
            if (lineItem["fromId"] == shapeId || lineItem["toId"] == shapeId) {
                self.stroeLines[lineId].line.remove();
                delete self.stroeLines[lineId];
            }
        });
        if (typeof (self.params.afterDelShape) == "function") {
            self.params.afterDelShape(shapeId);
        }
    };
    //清空画布
    HCIDbDesigner.prototype.clear = function () {

    };

    HCIDbDesigner.prototype.getData = function () {
        var self = this, shapes = {}, lines = {};
        $.each(self.stroeShapes, function (index, item) {
            shapes[index] = {
                x: item["rect"].attr("x"),
                y: item["rect"].attr("y"),
                data: item["data"]
            }
        });
        $.each(self.stroeLines, function (index, item) {
            lines[index] = {"fromId": item["fromId"], "toId": item["toId"]};
        });
        return {shapes: shapes, lines: lines};
    };

    return HCIDbDesigner;

})